﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using KOPLibrary.DataManagement;
using System.Net.Mail;
using KOPLibrary.Controls;
using System.Threading;
using KOPLibrary.TemplateManagement;
using System.IO;
using KOPLibrary.MailManagement;

namespace KOPLibrary.Forms
{
    public partial class eMailForm : Form
    {
        private TemplateType templateType;
        private AbstractData data;
        private Microsoft.Office.Interop.Word.Document defaultDocument;
        private WordManager manager;

        private WordManager Manager
        {
            get
            {
                if (manager == null)
                {
                    if (defaultDocument != null)
                        manager = new WordManager(defaultDocument.Application);
                    else manager = new WordManager(new Microsoft.Office.Interop.Word.Application());
                }
                return manager;
            }
            set
            {
                manager = value;
            }
        }

        public eMailForm()
        {
            InitializeComponent();
            ctlMsgBody.MaxLength = int.MaxValue;
        }

        public void Execute(AbstractData data, TemplateType templateType)
        {
            Execute(data, templateType, null, null);
        }

        public void Execute(AbstractData data, TemplateType templateType, Microsoft.Office.Interop.Word.Document defaultDoc, string eMailColumn)
        {
            this.data = data;
            this.templateType = templateType;
            if (templateType == TemplateType.Word)
                ctlBodyTab.TabPages.Remove(ctlTextTab);
            this.defaultDocument = defaultDoc;
            if (defaultDocument != null)
            {
                ctlSelectWordDoc.Enabled = false;
                ctlSelectedWord.Text = defaultDocument.FullName;
            }
            ctlEMailCol.DataSource = data;
            ctlNameCol.DataSource = data;
            ctlDataCol.DataSource = data;
            ctlColList2.DataSource = data;
            ctlColList3.DataSource = data;
            ctlColList4.DataSource = data;
            ctlsmtpSettings.LoadSettings();
            if (!string.IsNullOrEmpty(eMailColumn))
                ctlEMailCol.SelectedColumn = eMailColumn;
            ShowDialog();
        }

        private void ctlsmtpSettings_Load(object sender, EventArgs e)
        {

        }

        private void ctlGo_Click(object sender, EventArgs e)
        {
            if (ctlEMailCol.IsEmpty())
            {
                Util.ShowError("Lütfen hangi sütunun e-posta adresiolarak kullanılacağını belirtiniz");
                ctlEMailCol.Focus();
                return;
            }

            if (ctlBodyTab.SelectedTab == ctlTextTab)
            {
                if (ctlSubject.Text.Trim().Length == 0 ||
                    ctlMsgBody.Text.Trim().Length == 0)
                {
                    if (!Util.Confirm("Konu veya içerik olmadan mesaj göndermek istiyor musunuz?"))
                        return;
                }
            }
            else
            {
                if (ctlSelectedWord.Tag != null)
                {
                    Manager = new WordManager(new Microsoft.Office.Interop.Word.Application());
                    defaultDocument = Manager.OpenWordDocument(ctlSelectedWord.Text, string.Empty);

                }
                else if (defaultDocument == null)
                {
                    Util.ShowError("Lütfen e-posta içeriği olarak kullanmak istediğiniz Word dosyasını seçiniz");
                    return;
                }
                ctlContentType.SelectedIndex = 1;
            }

            if (Util.Confirm(string.Format("{0} kişiye e-posta gönderilmesini onaylıyor musunuz?", data.ItemArray.Count)))
            {
                int count = SendEMail();
                if (count == data.Count)
                    Util.ShowMessage("E-posta gönderme işlemi başarıyla tamamlandı");
                else if (count > 0)
                    Util.ShowMessage(string.Format("E-posta gönderme işlemi kısmen tamamlandı. Başarıyla gönderilen mesaj: {0} / {1}", count, data.Count));
            }
            DestroyResources();
            if (templateType == TemplateType.Word)
                Close();
        }

        private int SendEMail()
        {
            return SendEMail(data.Count);
        }

        private int SendEMail(int maxCount)
        {
            ProgressForm form = new ProgressForm();
            SmtpClient client = new SmtpClient();
            ctlsmtpSettings.SetClient(client);
            SmtpSettingsInfo smtpSettings = ctlsmtpSettings.Settings;
            form.Initialize(1, data.Count, "İşleme başlanılıyor ...", true, this);
            int successCount = 0;
            string boundText = string.Empty;
            
            HtmlBodyData bodyData = null;
            if (ctlBodyTab.SelectedTab == ctlWord)
            {
                form.SetMessage("Word ile iletişim kuruluyor ...");
                try
                {
                    bodyData = GetHtmlBodyData();
                }
                catch (Exception exc)
                {
                    Util.ShowException(exc);
                    DestroyResources();
                }
                boundText = bodyData.HtmlBody;
            }
            else boundText = ctlMsgBody.Text;

            for (int i = 0; i < maxCount; i++)
            {
                try
                {
                    MailMessage msg = new MailMessage(new MailAddress(smtpSettings.FromAddress, smtpSettings.FromName),
                        new MailAddress(data.Eval(i, ctlEMailCol.SelectedColumn), data.Eval(i, ctlNameCol.SelectedColumn)));
                    msg.Subject = data.Bind(i, ctlSubject.Text);
                    msg.IsBodyHtml = ctlContentType.SelectedIndex == 1;
                    msg.Body = data.Bind(i, boundText, data.Columns);
                    if (bodyData != null)
                    {
                        foreach (var att in bodyData.Attachments) msg.Attachments.Add(att);
                    }

                    ManageAttachments(i, msg);

                    form.Update(string.Format("Gönderiliyor {0} / {1}: {2}", i + 1, data.Count, msg.To[0].DisplayName + " (" + msg.To[0].Address + ")"));
                    client.Send(msg);
                    successCount++;
                    if (form.Canceled)
                        break;
                }
                catch (Exception exc)
                {
                    Util.ShowException(exc);
                    if (!Util.Confirm("e-Posta gönderme işlemine kaldığı yerden devam edilsin mi ?"))
                        break;
                }
            }
            form.Done();
            return successCount;
        }

        private void AddAttachment(string fileName, MailMessage msg)
        {
            string file = Path.GetFileName(fileName);
            file = Util.NormalizeFileName(file, "");
            fileName = Path.Combine(Path.GetDirectoryName(fileName), file);
            if (!File.Exists(fileName) && !ctlIgnoreAttach.Checked)
                throw new ArgumentException(fileName + " dosyası bulunamadı.");
            Attachment att = new Attachment(fileName);
            msg.Attachments.Add(att);
        }


        private void ManageAttachments(int row, MailMessage msg)
        {
            if (!string.IsNullOrEmpty(ctlAttach1.Text))
                AddAttachment(data.Bind(row, ctlAttach1.Text), msg);

            if (!string.IsNullOrEmpty(ctlAttach2.Text))
                AddAttachment(data.Bind(row, ctlAttach2.Text), msg);

            if (!string.IsNullOrEmpty(ctlAttach3.Text))
                AddAttachment(data.Bind(row, ctlAttach3.Text), msg);
        }


        private void DestroyResources()
        {
            if (templateType == TemplateType.Excel && defaultDocument != null)
            {
                try
                {
                    defaultDocument.Application.Quit();
                }
                catch { };
                defaultDocument = null;
            }

            Manager = null;
        }

        private HtmlBodyData GetHtmlBodyData()
        {
            object tempFile = Path.GetTempFileName();
            if (File.Exists(tempFile.ToString()))
                File.Delete(tempFile.ToString());
            string defFileName = defaultDocument.FullName;
            defaultDocument.SaveAs(FileName: tempFile);
            AbstractData columnData = new AbstractData();
            foreach (string column in data.Columns)
            {
                columnData.Columns.Add(column);
            }
            columnData.CreateTemplateData();
            Manager.BindDocument(defaultDocument, columnData, 0);
            HtmlBodyData html = MailManager.DocToHtmlForMail(defaultDocument, templateType == TemplateType.Excel);
            defaultDocument = null;
            DestroyResources();

            return html;
        }




        private void eMailForm_Load(object sender, EventArgs e)
        {
            ctlContentType.SelectedIndex = 0;
            ctlFieldDest.SelectedIndex = 0;
        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }

        private void ctlAddField_Click(object sender, EventArgs e)
        {
            TextBox txt;
            if (ctlFieldDest.SelectedIndex == 0)
                txt = ctlSubject;
            else txt = ctlMsgBody;
            txt.Select();
            txt.SelectedText = "{#" + ctlDataCol.SelectedColumn + " #}";
        }



        private void ctlSelectWordDoc_Click(object sender, EventArgs e)
        {
            if (ofdWord.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                ctlSelectedWord.Text = ofdWord.FileName;
                ctlSelectedWord.Tag = true;
            }
        }

        private void ctlCreateSampleDoc_Click(object sender, EventArgs e)
        {
            TemplateDesigner form = new TemplateDesigner(null, TemplateType.Excel , data, true);
            form.ShowDialog();
        }

        private void ctlSendTest_Click(object sender, EventArgs e)
        {
            if (ctlEMailCol.IsEmpty())
            {
                Util.ShowError("Lütfen hangi sütunun e-posta adresiolarak kullanılacağını belirtiniz");
                ctlEMailCol.Focus();
                return;
            }
            if (Util.Confirm(string.Format("Bu işlemle {0} e-posta adresine bir adet test mesajı gönderilecektir", data.Eval(0, ctlEMailCol.SelectedColumn))))
                SendEMail(1);
        }

        private TextBox FocusedAttach
        {
            get
            {
                if (ctlAttach1.Focused)
                    return ctlAttach1;
                else if (ctlAttach2.Focused)
                    return ctlAttach2;
                else if (ctlAttach3.Focused)
                    return ctlAttach3;
                else
                {
                    ctlAttach1.Focus();
                    return ctlAttach1;
                }
            }
        }

        private void ctlBrowseFile_Click(object sender, EventArgs e)
        {
            
            if (ctlOf.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
                ctlAttach1.Text = ctlOf.FileName;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ctlAttach1.Select();
            ctlAttach1.SelectedText = AbstractData.Qualify(ctlColList2.SelectedColumn);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (ctlOf.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                ctlAttach2.Text = ctlOf.FileName;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (ctlOf.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                ctlAttach2.Text = ctlOf.FileName;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            ctlAttach2.Select();
            ctlAttach2.SelectedText = AbstractData.Qualify(ctlColList3.SelectedColumn);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            ctlAttach3.Select();
            ctlAttach3.SelectedText = AbstractData.Qualify(ctlColList4.SelectedColumn);
        }

    }
}
